package icraf.carbon.gui;

import icraf.carbon.core.Project;
import icraf.carbon.core.Zone;
import icraf.carbon.core.ZoneList;
import icraf.carbon.gui.MenuFactory.MenuProperty;
import icraf.common.gui.MenuGenerator.IconModel;

import java.awt.BorderLayout;
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.HashMap;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.ListModel;

public class ZoneTransformPanel extends JPanel {
	private boolean isTransform;

	public class Listener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource().equals(importB)) {
				isTransform = true;
				dialogWindow.setVisible(false);
			} else if (e.getSource().equals(cancelB)) {
				isTransform = false;
				dialogWindow.setVisible(false);
			} 

		}

	}

	class SheetTableModel extends MatrixTableModel {
		private static final long serialVersionUID = 8654615864074536443L;

		private boolean editable = true;
		private NumberRowHeader numberRowHeaderModel = new NumberRowHeader(this);
		private String[][] data = new String[1][1];

		public SheetTableModel() {
			super();
		}

		@Override
		public Class<?> getColumnClass(int columnIndex) {
			return String.class;
		}

		@Override
		public int getColumnCount() {
			if (data != null)
				return data[0].length;
			return 0;
		}

		@Override
		public String getColumnName(int col) {
			return String.valueOf(col + 1);

		}

		@Override
		public int getRowCount() {
			if (data != null)
				return data.length;
			return 0;
		}

		@Override
		public ListModel<Object> getRowHeaderModel() {
			return numberRowHeaderModel;
		}

		@Override
		public Object getValueAt(int row, int column) {
			if (data == null)
				return null;
			if (row >= 0 && row < data.length && column >= 0
					&& column < data[row].length)
				return data[row][column];
			return null;
		}

		@Override
		public boolean isCellEditable(int row, int col) {
			return editable;
		}

		@Override
		public void setValueAt(Object value, int row, int col) {

			if (row >= 0 && row < data.length && col >= 0
					&& col < data[0].length)
				data[row][col] = value.toString();
			fireTableCellUpdated(row, col);
		}

		public String[][] getData() {
			return data;
		}

		public void setData(String[][] data) {
			this.data = data;
			fireTableStructureChanged();
		}

	}

	class ZoneTransitionTableModel extends MatrixTableModel  {
		private static final long serialVersionUID = 8654615864074536443L;

		private boolean editable = true;
		private DecimalFormat formatter = (DecimalFormat) NumberFormat
				.getNumberInstance();
		private ZoneRowHeaderModel zoneRowHeaderModel = new ZoneRowHeaderModel(this);
		private Project project;

		private HashMap<Zone, HashMap<Zone, Double>> transformFactor = new HashMap<Zone, HashMap<Zone, Double>>();

		public ZoneTransitionTableModel() {
			super();
		}

		@Override
		public Class<?> getColumnClass(int columnIndex) {
			return Double.class;
		}

		@Override
		public int getColumnCount() {
			if (project != null) {
				//return project.getLandCoverList().size();
				return project.getZoneList().getSize();
			}
			return 0;
		}

		@Override
		public String getColumnName(int col) {
			if (project == null)
				return "";
			//return project.getLandCoverList().get(col).getLabel();
			return project.getZoneList().get(col).getLabel();

		}

		public Project getProject() {
			return project;
		}

		@Override
		public int getRowCount() {
			if (project == null)
				return 0;
			//return project.getLandCoverList().size();
			return project.getZoneList().getSize();
		}

		@Override
		public ListModel<Object> getRowHeaderModel() {
			return zoneRowHeaderModel;
		}

		@Override
		public Object getValueAt(int row, int col) {
			if (project == null)
				return 0d;

			ZoneList l = project.getZoneList();
			Zone lcRow;
			Zone lcCol;

			lcRow = l.get(row);
			lcCol = l.get(col);

			double val = getValue(lcRow, lcCol);

			if (Double.isNaN(val))
				return 0d;
			return val;
		}

		@Override
		public boolean isCellEditable(int row, int col) {
			return editable;
		}

		public void setProject(Project p) {
			this.project = p;
			zoneRowHeaderModel.setProject(p);
			fireTableStructureChanged();
		}

		@Override
		public void setValueAt(Object value, int row, int col) {
			if (value == null)
				return;

			double d = 0;

			if (value instanceof String) {
				String strVal = (String) value;
				strVal = strVal.replaceAll( "[^\\d.,-Ee]", "" );
				try {
					d = formatter.parse(strVal.trim()).doubleValue();
				} catch (Exception e) {
					return;
				}
			} else {
				d = ((Double) value).doubleValue();
			}

			ZoneList l = project.getZoneList();
			Zone lcRow;
			Zone lcCol;

			lcRow = l.get(row);
			lcCol = l.get(col);

			setValue(d, lcRow, lcCol);
			fireTableCellUpdated(row, col);
		}

		public void setValue(double d, Zone z1, Zone z2) {
			HashMap<Zone, HashMap<Zone, Double>> data = transformFactor;

			HashMap<Zone, Double> lc1List = data.get(z1);
			if (lc1List == null) {
				lc1List = new HashMap<Zone, Double>();
			}
			lc1List.put(z2, d);
			data.put(z1, lc1List);
		}

		public double getValue(Zone z1, Zone z2) {
			HashMap<Zone, HashMap<Zone, Double>> data = transformFactor;
			if ((z1 == null) || (z2 == null)) {
				return Double.NaN;
			}
			HashMap<Zone, Double> lc1List = data.get(z1);
			if (lc1List == null)
				return Double.NaN;
			if (lc1List.get(z2) == null)
				return Double.NaN;
			double d = lc1List.get(z2);
			return d;
		}

		public void clearData() {
			transformFactor.clear();
		}

	}

	private static final long serialVersionUID = -6267507992297896197L;
	private MatrixPanel clipboardTablePanel;
//	private Clipboard system;
//	private int nColumn = 0;
	private ZoneTransitionTableModel zoneTableModel = new ZoneTransitionTableModel();
//	private String[][] data;
	private Listener listener = new Listener();
//	public ArrayList<String> columnError = new ArrayList<String>();
//	public ArrayList<String> rowError = new ArrayList<String>();
	private JButton importB = MenuFactory.createButton(MenuProperty.GENERAL_TRANSFORM, listener, true, IconModel.ICON16);
	private JButton cancelB = MenuFactory.createButton(MenuProperty.INPUT_CANCEL, listener, true, IconModel.ICON16);
	private JDialog dialogWindow;
//	private boolean isLCClipboard = true;
	
	public ZoneTransformPanel() {
		super();
		clipboardTablePanel = new MatrixPanel(zoneTableModel, true, false, true,
				false, true);

		JPanel pb = new JPanel();
		pb.add(importB);
		pb.add(cancelB);
		
		this.setLayout(new BorderLayout());
		this.add(clipboardTablePanel, BorderLayout.CENTER);
		this.add(pb, BorderLayout.SOUTH);
	}

//	public void updateClipboardData() {
//		system = Toolkit.getDefaultToolkit().getSystemClipboard();
//		try {
//			String trstring = (String) (system.getContents(this)
//					.getTransferData(DataFlavor.stringFlavor));
//			String lineStr[] = trstring.split("\n");
//			String val[] = lineStr[0].split("\t");
//			nColumn = val.length;
//			data = new String[lineStr.length][nColumn];
//			for (int i = 0; i < lineStr.length; i++) {
//				data[i] = lineStr[i].split("\t");
//			}
//			updateTable();
//		} catch (Exception ex) {
//			// unsupported clipboard data
//		}
//	}

//	public void updateTable() {
//
//	}

	public void setProject(Project p) {
		zoneTableModel.setProject(p);
	}

	public ZoneTransitionTableModel getZoneTransformMatrix() {
		return zoneTableModel;
	}

//	public String[][] getData() {
//		return data;
//	}
	
	public JDialog createDialog(Window owner, ModalityType modalityType) {
		isTransform = false;
		JDialog dialog = new JDialog(owner, modalityType);
		dialog.getContentPane().add(this);
		dialog.setTitle(MenuProperty.GENERAL_TRANSFORM_MATRIX.getLabel());
		//dialog.setIconImage(MenuProperty.GENERAL_TRANSFORM_MATRIX.getIcon(IconModel.ICON16).getImage());
		dialog.pack();
		dialogWindow = dialog;
		return dialog;
	}

	public boolean isTransform() {
		return isTransform;
	}

//	public boolean isLCClipboard() {
//		return isLCClipboard;
//	}

//	public TableModel getLcTableModel() {
//		return zoneTableModel;
//	}

	public void clear() {
		zoneTableModel.clearData();
	}
}